﻿using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace BOBOScript.Script
{
    public class Function
    {
        public string? 函数名;
        public string? 函数返回类型;
        public int 函数开始位置;
        public int 函数结束位置;
        public 访问权限 权限 = 访问权限.None;
        public bool 静态函数 = false;
        public List<string>? 修饰符;
        public static bool Isfunction(string line)
        {
            return Regex.IsMatch(line, @".*\s*(function)\s+");
        }
        public static (Function, bool) 获取函数信息(string t)
        {
            Function Function_ = new Function();
            var strings = Tools.分割文本_空格(t);
            strings = Tools.取有效部分(ref strings);
            if (!(strings.Count >= 1))
            {
                Log.ErrorLine("[内部错误]成分分割错误");
                return (null, false);
            }
            if (strings[0] != "function")
            {
                Log.ErrorLine("[内部错误]不是函数的定义却使用了 获取函数信息()");
                return (null, false);
            }
            Function_.修饰符 = new List<string>();
            int p = -1;
            int a = -1;
            int index=-1;
            int LastIndex = -1;
            bool 位于开头=false;
            StringBuilder sb= new StringBuilder();
            for (int i = 0; i < strings.Count; i++)
            {
                if (a!=-1 && p!=-1)
                {
                    break;
                }
                if (index==-1)
                {
                    index = strings[i].IndexOf('(');
                    if (index == 0)
                    {
                        p = i;
                        位于开头 = true;
                    }
                    else
                    {
                        p = i;
                        位于开头 = false;
                    }
                }
                if (LastIndex == -1)
                {
                    LastIndex= strings[i].IndexOf(')');
                    if (LastIndex != -1)
                    {
                        a = i;
                    }
                }
                if (index != -1) 
                {
                    if (i==strings.Count-1)
                    {
                        sb.Append(strings[i]);
                    }
                    else
                    {
                        sb.Append(strings[i]+"\\");
                    }
                }
            }
            if (p>a)
            {
                Log.ErrorLine("右括号在左括号前\nat " + t);
                return (null, false);
            }
            Console.WriteLine(sb.ToString());
            if (index==-1)
            {
                Log.ErrorLine("函数定义需要括号\nat "+t);
                return (null, false);
            }
            int 返回值位置;
            int 范围;
            if (位于开头)
            {
                Function_.函数名 = strings[p - 1];
                返回值位置 = p - 2;

            }
            else
            {
                Function_.函数名 = strings[p].Substring(0,index);
                返回值位置 = p - 1;
            }
            Function_.函数返回类型 = strings[返回值位置];
            for (int i = 1; i < 返回值位置; i++)
            {
                if (strings[i] == "public")
                {
                    if (Function_.权限 != 访问权限.None)
                    {
                        Log.ErrorLine("多重访问权限\nat " + t);
                        return (null, false);
                    }
                    Function_.权限 = 访问权限.Public;
                    continue;
                }
                if (strings[i] == "private")
                {
                    if (Function_.权限 != 访问权限.None)
                    {
                        Log.ErrorLine("多重访问权限\nat " + t);
                        return (null, false);
                    }
                    Function_.权限 = 访问权限.Private;
                    continue;
                }
                if (strings[i] == "static")
                {
                    if (Function_.静态函数)
                    {
                        Log.WarningLine("多重静态修饰\nat " + t);
                    }
                    Function_.静态函数 = true;
                    continue;
                }
                Function_.修饰符.Add(strings[i]);
            }
            return (Function_, false); 
        }
    }
    public static class 括号单元_关键字识别
    {
        public static (bool 为关键字, 括号单元.单元类型 类型) 获取关键字(string text)
        {
            if (Function.Isfunction(text))
            {
                return (true, 括号单元.单元类型.函数);
            }
            if (类.IsClass(text))
            {
                return (true, 括号单元.单元类型.类);
            }
            return (false, 括号单元.单元类型.空);
        }
    }
    public class 括号单元
    {
        public int 开始位置=-1;
        public int 结束位置=-1;
        public 单元类型 类型;
        public string? 头;
        public enum 单元类型
        {
            空=-1,
            函数=1,
            IF语句=2,
            WHILE语句=3,
            类=4
        }
        public static List<括号单元> 获取单元(ref List<string> text)
        {
            List<括号单元> 单元集合 = new List<括号单元>();
            int 完备数量=0;
            for (int i = 0; i < text.Count; i++)
            {
                var type = 括号单元_关键字识别.获取关键字(text[i]);
                if (type.为关键字)
                {
                    括号单元 单元 = new 括号单元();
                    单元.头 = text[i];
                    单元.类型 = type.类型;
                    单元集合.Add(单元);
                }
                bool 在文本中 = false;
                for (int j = 0; j < text[i].Length; j++)
                {
                    if (text[i][j] == '"')
                    {
                        在文本中 = !在文本中;
                    }
                    if (!在文本中 && text[i][j] == '{')
                    {
                        //没有
                        if (单元集合.Count == 0)
                        {
                            Log.ErrorLine("没有被定义的可带括号的表达式,却出现了括号");
                        }
                        for (int y = 0; y < 单元集合.Count; y++)
                        {
                            //不完备且 开始 被填充
                            if (单元集合[单元集合.Count - y - 1].开始位置 != -1 && 单元集合[单元集合.Count - y - 1].结束位置 == -1)
                            {
                                Log.ErrorLine("括号配对错误!");
                            }
                            //完备
                            if (单元集合[单元集合.Count - y - 1].开始位置 != -1 && 单元集合[单元集合.Count - y - 1].结束位置 != -1)
                            {
                                continue;
                            }
                            if (单元集合[单元集合.Count - y - 1].开始位置 == -1)
                            {
                                单元集合[单元集合.Count - y - 1].开始位置 = i;
                                if (单元集合[单元集合.Count - y - 1].开始位置 != -1 && 单元集合[单元集合.Count - y - 1].结束位置 != -1)
                                {
                                    完备数量++;
                                }
                                break;
                            }
                        }
                    }
                    if (!在文本中 && text[i][j] == '}')
                    {
                        for (int y = 0; y < 单元集合.Count; y++)
                        {
                            //不完备且 结束 被填充
                            if (单元集合[单元集合.Count - y - 1].开始位置 == -1 && 单元集合[单元集合.Count - y - 1].结束位置 == -1)
                            {
                                Log.ErrorLine("括号配对错误!");
                            }
                            //完备
                            if (单元集合[单元集合.Count - y - 1].开始位置 != -1 && 单元集合[单元集合.Count - y - 1].结束位置 != -1)
                            {
                                continue;
                            }
                            if (单元集合[单元集合.Count - y - 1].结束位置 == -1)
                            {
                                单元集合[单元集合.Count - y - 1].结束位置 = i;
                                if (单元集合[单元集合.Count - y - 1].开始位置 != -1 && 单元集合[单元集合.Count - y - 1].结束位置 != -1)
                                {
                                    完备数量++;
                                }
                                break;
                            }
                        }
                    }
                }
            }
            if (单元集合.Count!=完备数量)
            {
                Log.ErrorLine("括号不匹配");
            }
            return 单元集合;
        }
    }
    public static class 四则运算
    {
        public static object 运算(string t)
        {
            using DataTable dt = new DataTable();
            return dt.Compute(t, "");
        }
    }
    public class 类
    {
        public string? 类名;
        public int 开始位置;
        public int 结束位置;
        public List<Function>? 函数;
        public 访问权限 权限= 访问权限.None;
        public List<string>? 修饰符;
        public bool 静态类=false;
        public static bool IsClass(string line)
        {
            return Regex.IsMatch(line, @".*\s*(class)\s+");
        }
        public static (类,bool) 获取类信息(string t)
        {
            类 类_ = new 类();
            var strings = Tools.分割文本_空格(t);
            strings = Tools.取有效部分(ref strings);
            if (!(strings.Count>=1))
            {
                Log.ErrorLine("[内部错误]成分分割错误");
                return (null, false);
            }
            if (strings[0]!="class")
            {
                Log.ErrorLine("[内部错误]不是类的定义却使用了 获取类信息()");
                return (null, false);
            }
            类_.修饰符 = new List<string>();
            string temp = strings[strings.Count - 1];
            类_.类名 = temp;
            for (int i = 1; i < strings.Count-1; i++)
            {
                if (strings[i]=="public")
                {
                    if (类_.权限!= 访问权限.None)
                    {
                        Log.ErrorLine("多重访问权限\nat " +t);
                        return (null, false);
                    }
                    类_.权限 = 访问权限.Public;
                    continue;
                }
                if (strings[i] == "private")
                {
                    if (类_.权限 != 访问权限.None)
                    {
                        Log.ErrorLine("多重访问权限\nat " + t);
                        return (null, false);
                    }
                    类_.权限 = 访问权限.Private;
                    continue;
                }
                if (strings[i] == "static")
                {
                    if (类_.静态类)
                    {
                        Log.WarningLine("多重静态修饰\nat " + t);
                    }
                    类_.静态类 = true;
                    continue;
                }
                类_.修饰符.Add(strings[i]);
            }
            return (类_, false);
        }
        /*
        public static (List<类>,bool) 从括号单元构建类(ref List<括号单元> 单元)
        {
            int index = -1;
            for (int i = 0; i < 单元.Count; i++)
            {
                if (单元[i].类型 != 括号单元.单元类型.类)
                {
                    if (单元[i].类型 == 括号单元.单元类型.函数)
                    {
                        if (index>=0 && 单元[i].结束位置<= 单元[index].结束位置)
                        {

                        }
                    }
                    continue;
                }
                var ret = 类.获取类信息(单元[i].头);
                if (!ret.Item2)
                {
                    return (null, false);
                }
                类 类_ = ret.Item1;
                类_.开始位置 = 单元[i].开始位置;
                类_.结束位置 = 单元[i].结束位置;
                index = i;
            }
        }*/
    }
    public enum 访问权限 
    { 
        None=-1,
        Public=1,
        Private=2
    }
}
